#include "usart.h"

// 引脚相关宏定义
#define USART1_TX_PIN GPIO9
#define USART1_RX_PIN GPIO10
#define USART2_TX_PIN GPIO2
#define USART2_RX_PIN GPIO3

// 初始化串口参数结构体，设置默认值
UsartParameters usart_default_params(void) {
    UsartParameters params = {
       .baudrate = 115200,
       .databits = 8,
       .stopbits = USART_STOPBITS_1,
       .parity = USART_PARITY_NONE,
       .flow_control = USART_FLOWCONTROL_NONE,
       .mode = USART_MODE_TX_RX
    };
    return params;
}

// 自动初始化指定串口，使用默认参数
void usart_auto_init(uint32_t usart) {
    UsartParameters params = usart_default_params();
    // 根据传入的串口使能对应的GPIO和USART时钟
    switch (usart) {
        case USART1:
            rcc_periph_clock_enable(RCC_GPIOA);
            rcc_periph_clock_enable(RCC_USART1);
            // 配置USART1的引脚
            gpio_set_mode(GPIOA,
                          GPIO_MODE_OUTPUT_50_MHZ,
                          GPIO_CNF_OUTPUT_ALTFN_PUSHPULL,
                          USART1_TX_PIN);  // TX引脚
            gpio_set_mode(GPIOA,
                          GPIO_MODE_INPUT,
                          GPIO_CNF_INPUT_FLOAT,
                          USART1_RX_PIN); // RX引脚
            break;
        case USART2:
            rcc_periph_clock_enable(RCC_GPIOA);
            rcc_periph_clock_enable(RCC_USART2);
            // 配置USART2的引脚
            gpio_set_mode(GPIOA,
                          GPIO_MODE_OUTPUT_50_MHZ,
                          GPIO_CNF_OUTPUT_ALTFN_PUSHPULL,
                          USART2_TX_PIN);  // TX引脚
            gpio_set_mode(GPIOA,
                          GPIO_MODE_INPUT,
                          GPIO_CNF_INPUT_FLOAT,
                          USART2_RX_PIN); // RX引脚
            break;
        default:
            break;
    }

    // 配置串口参数
    usart_set_baudrate(usart, params.baudrate);
    usart_set_databits(usart, params.databits);
    usart_set_stopbits(usart, params.stopbits);
    usart_set_parity(usart, params.parity);
    usart_set_flow_control(usart, params.flow_control);
    usart_set_mode(usart, params.mode);

    // 使能串口
    usart_enable(usart);
}

// 手动初始化指定串口，使用自定义参数
void usart_manual_init(uint32_t usart, const UsartParameters *params) {
    // 根据传入的串口使能对应的GPIO和USART时钟
    switch (usart) {
        case USART1:
            rcc_periph_clock_enable(RCC_GPIOA);
            rcc_periph_clock_enable(RCC_USART1);
            // 配置USART1的引脚
            gpio_set_mode(GPIOA,
                          GPIO_MODE_OUTPUT_50_MHZ,
                          GPIO_CNF_OUTPUT_ALTFN_PUSHPULL,
                          USART1_TX_PIN);  // TX引脚
            gpio_set_mode(GPIOA,
                          GPIO_MODE_INPUT,
                          GPIO_CNF_INPUT_FLOAT,
                          USART1_RX_PIN); // RX引脚
            break;
        case USART2:
            rcc_periph_clock_enable(RCC_GPIOA);
            rcc_periph_clock_enable(RCC_USART2);
            // 配置USART2的引脚
            gpio_set_mode(GPIOA,
                          GPIO_MODE_OUTPUT_50_MHZ,
                          GPIO_CNF_OUTPUT_ALTFN_PUSHPULL,
                          USART2_TX_PIN);  // TX引脚
            gpio_set_mode(GPIOA,
                          GPIO_MODE_INPUT,
                          GPIO_CNF_INPUT_FLOAT,
                          USART2_RX_PIN); // RX引脚
            break;
        default:
            break;
    }

    // 配置串口参数
    usart_set_baudrate(usart, params->baudrate);
    usart_set_databits(usart, params->databits);
    usart_set_stopbits(usart, params->stopbits);
    usart_set_parity(usart, params->parity);
    usart_set_flow_control(usart, params->flow_control);
    usart_set_mode(usart, params->mode);

    // 使能串口
    usart_enable(usart);
}

// 发送一个字节
void usart_send_byte(uint32_t usart, uint8_t byte) {
    // 等待发送数据寄存器为空
    while (!(usart_get_flag(usart, USART_SR_TXE)));
    usart_send(usart, (uint16_t)byte);
}

// 发送字符串
void usart_send_string(uint32_t usart, const char *str) {
    while (*str) {
        usart_send_byte(usart, *str++);
    }
}

// 接收一个字节（阻塞式）
uint8_t usart_recv_byte(uint32_t usart) {
    // 等待接收数据寄存器非空
    while (!(usart_get_flag(usart, USART_SR_RXNE)));
    return (uint8_t)usart_recv(usart);
}
// # 示例
int example(void) {
    // 自动初始化USART1，使用默认参数
    usart_auto_init(USART1);
    usart_send_string(USART1, "USART1 auto initialized, using default settings.\r\n");

    // 手动初始化USART2，自定义参数
    UsartParameters custom_params = {
        .baudrate = 9600,
        .databits = 8,
        .stopbits = USART_STOPBITS_1,
        .parity = USART_PARITY_NONE,
        .flow_control = USART_FLOWCONTROL_NONE,
        .mode = USART_MODE_TX_RX
     };
    usart_manual_init(USART2, &custom_params);
    usart_send_string(USART2, "USART2 manually initialized, using custom settings.\r\n");

    while (1) {
        // 主循环中可以进行数据的接收和发送操作
        // 例如：
        // uint8_t received_byte = usart_recv_byte(USART1);
        // usart_send_byte(USART1, received_byte);
    }

    return 0;
}
